home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
apps
/
42
/
wind4.prf
< prev
next >
Wrap
Text File
|
1986-07-17
|
19KB
|
328 lines
.!****************************************************************************
.!
.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION.
.!
.! ** Professional GEM ** by Tim Oren
.!
.! Proff File by ST enthusiasts at
.! Case Western Reserve University
.! Cleveland, Ohio
.! uucp : decvax!cwruecmp!bammi
.! csnet: bammi@case
.! arpa : bammi%case@csnet-relay
.! compuserve: 71515,155
.!
.!****************************************************************************
.!
.!
.!****************************************************************************
.!
.! Begin Part 4
.!
.!****************************************************************************
.!
.PART IV Resource Structure
.PP
Welcome to the fourth installment of ST PRO GEM. We are about to delve into
the mysteries of GEM resource structure, and then use this knowledge to create
some useful utilities for handling dialogs. As with the past columns, there is
once again a download file. You will find it under the name GEMCL4.C in the
ATARI 16-bit Forum (GO PCS-58).
.PP
The first and largest part of the download contains a C image of a sample
resource file. To create this listing, I used the GEM Resource Construction
Set to create a dummy resource with three dialogs including examples of all
object types, then enabled the C output option and saved the resource. If you
have access to a copy of RCS, I suggest that you create your own listing in
order to get a feel for the results. Then, using either listing as a roadmap
to the resource, you can follow along as we enter...
.SH A MAZE OF TWISTY LITTLE PASSAGES.
While a GEM resource is loaded as a block of binary information, it
is actually composed of a number of different data structures. These
structures are linked together in a rather tangled hierarchy. Our
first job is to map this linkage system.
.PP
The topmost structure in a resource file is the resource header. This is an
array of words containing the size and offset within the resource of the other
structures which follow. This information is used by GEM during the resource
load process, and you should never need to access it. (The resource header does
not appear in the C output file; it is generated by the RSCREATE utility if the
C file is used to recreate the resource.)
.PP
The next structure of interest is the tree index. This is an array of long
pointers, each of which addresses the beginning of an object tree. Again, you
wouldn't normally access this structure directly. The GEM rsrc_gaddr call uses
it when finding trees' addresses. This structure is called "rs_trindex" in the
C output.
.PP
If you look at the contents of rs_trindex you will notice that the values are
integers, instead of the pointers I described. What has happened is that RCS
has converted the pointers to indices into the object array. (If you actually
used the C file to recreate the resource file, then the pointers would be
regenerated by RSCREATE.)
.PP
Now you can follow the link from rs_trindex to the objects stored in
rs_object. Take (for instance) the second entry in rs_trindex and count down
that many lines in rs_object. The following line (object) should start with a
-1. This indicates that it is the root object of a tree. The following objects
down to the next root belong to that tree. We'll pass over the details of
inter-object linkage for now, leaving it for a later column.
.PP
There are a number of different fields in an object, but right now we'll
concentrate on two of them: OB_TYPE and OB_SPEC. The OB_TYPE is the field which
contains mnemonics like G_STRING and G_BOX indicating the type of the object.
The OB_SPEC is the only field in each object which is a LONG - you can tell it
by the L after the number.
.PP
What's in OB_SPEC depends on the object type, so we need to talk about what
kinds of objects are available, what you might use them for, and finally how
they use the OB_SPEC field.
.PP
The box type objects are G_BOX, G_IBOX, and G_BOXCHAR. A G_BOX is an opaque
rectangle, with an optional border. It's used to create a solid patch of color
or pattern on which to place other objects. For instance, the background of a
dialog is a G_BOX.
.PP
A G_IBOX is a hollow box which has only a border. (If the border has no
thickness, then the box is "invisible", hence the name.) The favorite use for
IBOXes is to hold radio buttons. There is also one neat trick you can play with
an IBOX. If you have more than one object (say an image and a string) which you
would like to have selected all at once, you can insert them in a dialog, then
cover them with an IBOX. Since the box is transparent, they will show through.
If you now make the box selectable, clicking on it will highlight the whole area
at once!
.PP
The G_BOXCHAR is just like a G_BOX, except that a single character is drawn
in its center. They are mostly used as "control points": the FULLER, CLOSER,
SIZER, and arrows in GEM windows are BOXCHARs, as are the components of the
color selection gadgets in the RCS.
.PP
The OB_SPEC for box type objects is a packed bit array. Its various fields
contain the background color and pattern, the border thickness and color, and
the optional character and its color.
.PP
The string type objects are G_STRING, G_BUTTON, and G_TITLE. G_STRINGs (in
addition to being a bad pun) are for setting up static explanatory text within
dialogs. The characters are always written in the "system font": full size,
black, with no special effects.
.PP
We have already discussed many of the uses of G_BUTTONs. They add a border
around the text. The thickness of a G_BUTTON's border is determined by what
flags are set for the object. All buttons start out with a border thickness of
one pixel. One pixel is added if the EXIT attribute is set, and one more is
added if the DEFAULT attribute is set.
.PP
The G_TITLE type is a specially formatted text string used only in the title
bar of menus. This type is needed to make sure that the menus redraw correctly.
The Resource Construction Set automatically handles inserting G_TITLEs, so you
will seldom use them directly.
.PP
In a resource, the OB_SPEC for all string objects is a long pointer to a null
terminated ASCII string. The string data in the C file is shown in the BYTE
array rs_strings. Again you will notice that the OB_SPECs in the C file have
been converted to indices into rs_string. To find the string which matches the
object, take the value of OB_SPEC and count down that many lines in rs_strings.
The next line is the correct string.
.PP
The formatted text object types are G_TEXT, G_BOXTEXT, G_FTEXT, and
G_FBOXTEXT. G_TEXTs are a lot like strings, except that you can specify a
color, different sizes, and a positioning rule for the text. Since they
require more memory than G_STRINGs, G_TEXTs should be used sparingly to draw
attention to important information within a dialog. G_TEXTs are also useful
for automatic centering of dialog text which is changed at run-time. I will
describe this technique in detail later on.
.PP
The G_BOXTEXT type adds a solid background and border to the G_TEXT type.
These objects are occasionally used in place of G_BUTTONs when their color will
draw attention to an important object.
.PP
The G_FTEXT object is an editable text field. You are able to specify a
constant "template" of characters, a validation field for those characters which
are to be typed in, and an initial value for the input characters. You may also
select color, size, and positioning rule for G_FTEXTs. We'll discuss text
editing at length below.
.PP
The G_FBOXTEXT object, as you might suspect, is the same as G_FTEXT with the
addition of background and border. This type is seldom used: the extra
appearance details distract attention from the text being edited.
.PP
The OB_SPEC for a formatted text object is a pointer to yet another type of
structure: a TEDINFO. In the C file, you will find these in rs_tedinfo. Take
the OB_SPEC value from each text type object and count down that many entries in
rs_tedinfo, finding the matching TEDINFO on the next line. Each contains
pointers to ASCII strings for the template, validation, and initialization. You
can find these strings in rs_strings, just as above.
.PP
There are also fields for the optional background and border details, and for
the length of the template and text. As we will see when discussing editing,
the most important TEDINFO fields are the TE_PTEXT pointer to initialized text
and the TE_TXTLEN field which gives its length.
.PP
The G_IMAGE object type is the only one of its kind. A G_IMAGE is a
monochrome bit image. For examples, see the images within the various GEM alert
boxes. Note that monochrome does not necessarily mean black. The image may be
any color, but all parts of it are the SAME color. G_IMAGEs are used as visual
cues in dialogs. They are seldom used as selectable items because their entire
rectangle is inverted when they are clicked. This effect is seldom visually
pleasing, particularly if the image is colored.
.PP
G_IMAGE objects have an OB_SPEC which is a pointer to a further structure
type: the BITBLK. By now, you should guess that you will find it in the C file
in the array rs_bitblk. The BITBLK contains fields describing the height and
width of the image in pixels, its color,nd it also contains a long pointer to
the actual bits which make up the image. In the C file, the images are encoded
as hexadecimal words and stored in arrays named IMAG0, IMAG1, and so on.
.PP
The last type of object is the G_ICON. Like the G_IMAGE, the G_ICON is a bit
image, but it adds a mask array which selects what portions of the image will be
drawn, as well as an explanatory text field. A G_ICON may also specify
different colors for its "foreground" pixels (the ones that are normally black),
and its "background" pixels (which are normally white).
.PP
The pictures which you see in Desktop windows are G_ICONs, and so are the
disks and trashcan on the desktop surface. With the latter you will notice the
effects of the mask. The desktop shows through right up to the edge of the
G_ICON, and only the icon itself (not a rectangle) is inverted when a disk is
selected.
.PP
The OB_SPEC of an icon points to another structure called an ICONBLK. It is
shown in the C file as rs_iconblk. The ICONBLK contains long pointers to its
foreground bit array, to the mask bit array, and to the ASCII string of
explanatory text. It also has the foreground and background colors as well as
the location of the text area from the upper left of the icon. The most common
use of G_ICONs and ICONBLKs is not in dialogs, instead they are used frequently
in trees which are build at run-time, such as Desktop windows. In a future
article, we will return to a discussion of building such "on-the-fly" trees with
G_ICONs.
.PP
Now, let's recap the hierarchy of resource structures: The highest level
structures are the resource header, and then the tree index. The tree index
points to the beginning of each object tree. The objects making up the tree are
of several types, and depending on that type, they may contain pointers to ASCII
strings, or to TEDINFO, ICONBLK, or BITBLK structures. TEDINFOs contain further
pointers to strings; BITBLKs have pointers to bit images; and ICONBLKs have
both.
.SH PUTTING IT TO WORK
The most common situations requiring you to understand
resource structures involve the use of text and editable text objects in
dialogs. We'll look at two such techniques.
.PP
Often an application requires two or more dialogs which are very similar
except for one or two title lines. In this circumstance, you can save a good
deal of resource space by building only one dialog, and changing the title at
run time.
.PP
It is easy to go wrong with this practice, however, because the obvious
tactic of using a G_STRING and writing over its text at run time can go wrong.
The first problem is that you must know in advance the longest title to be used,
and put a string that long into the resource. If you don't you will damage other
objects in the resource as you copy in characters. The other problem is that a
G_STRING is always drawn at the same place in a dialog. If the length of the
title changes from time to time, the dialog will have an unbalanced and sloppy
appearance.
.PP
A better way to do this is to exploit the G_TEXT object type, and the TEDINFO
structure. The set_text() routine in the download shows how. The parameters
provided are the tree address, the object number, and the 32-bit address of the
string to be substituted. For this to work, the object referenced should be
defined as a G_TEXT type object. Additionally, the Centered text type should
be chosen, and the object should have been "stretched" so that it fills the
dialog box from side to side.
.PP
In the code, the first action is to get the OB_SPEC from the object which was
referenced. Since we know that the object is a G_TEXT, the OB_SPEC must point
to a TEDINFO. We need to change two fields in the TEDINFO. The TE_PTEXT field
is the pointer to the actual string to be displayed; we replace it with the
address of our new string. The TE_TXTLEN field is loaded with the new string's
length. Since the Centered attribute was specified for the object, changing the
TE_TXTLEN will cause the string to be correctly positioned in the middle of the
dialog!
.PP
Editing text also requires working with the TEDINFO structure. One way of
doing this is shown in the download. The object to be used (EDITOBJ) is assumed
to be a G_FTEXT or G_FBOXTEXT. Since we will replace the initialized text at
run time, that field may be left empty when building the object in the RCS.
.PP
The basic trick of this code is to point the TEDINFO's TE_PTEXT at a string
which is defined in your code's local stack. The advantages of this technique
are that you save resource space, save static data by putting the string in
reusable stack memory, and automatically create a scratch string which may be
discarded if the dialog is cancelled.
.PP
The text string shown is arbitrarily 41 characters long. You should give
yours a length equal to the number of blanks in the object's template field plus
one. Note that the code is shown as a segment, rather than a subroutine. This
is required because the text string must be allocated within the context of
dialog handling routine itself, rather than a routine which it calls!
.PP
After the tree address is found, the code proceeds to find the TEDINFO and
modify its TE_PTEXT as described above. However, the length which is inserted
into TE_TXTLEN must be the maximum string length, including the null!
.PP
The final line of code inserts a null into the first character of the
uninitialized string. This will produce an empty editing field when the dialog
is displayed. If there is an existing value for the object, you
should instead use strcpy() to move it into text[]. Once the dialog is
complete, you should check its final status as described in the last
article. If an "OK" button was clicked, you will then use strcpy() to
move the value in text[] back to its static location.
.PP
Although I prefer this method of handling editable text, another method
deserves mention also. This procedure allocates a full length text string of
blanks when creating the editable object in the RCS. At run-time, the TE_PTEXT
link is followed to find this string's location in the resource, and any
pre-existing value is copied in. After the dialog is run, the resulting value is
copied back out if the dialog completed successfully.
.PP
Note that in both editing techniques a copy of the current string value is
kept within the application's data area. Threading the resource whenever you
need to check a string's value is extremely wasteful.
.PP
One final note on editable text objects: GEM's editor uses the commercial at
sign '@' as a "meta-character". If it is the first byte of the initialized
text, then the field is displayed blank no matter what follows. This can be
useful, but is sometimes confusing when a user in all innocence enters an @ and
has his text disappear the next time the dialog is drawn!
.SH LETTERS, WE GET LETTERS
The Feedback section on ANTIC ST ONLINE is now
functional and is producing a gratifying volume of response. A number of
requests were made for topics such as ST hardware and ST BASIC which are beyond
the intended scope of this column. These have been referred to ANTIC's
editorial staff for action.
.PP
So many good GEM questions were received that I will devote part of the next
column to answering several of general interest. Also, your requests have
resulting in scheduling future columns on VDI text output and on the principles
(or mythology) of designing GEM application interfaces. Finally, a tip of the
hat to the anonymous reader who suggested including the actual definitions of
all macro symbols, so that those without the appropriate H files can follow
along. As a result of this suggestion, the definitions for this column and the
previous three are included at the end of the download. Future articles will
continue this practice.
.SH STRAW POLL!
I'd like to make a practice of using the Feedback to get your
opinions on the column's format. As a first trial, I'd like to know your
feelings about my use of "portability macros" in the sample code. These macros,
LLGET for example, are used for compatibility between 68K GEM systems like the
ST, and Intel based systems like the IBM PC. This may be important to many
developers. On the other hand, omitting them results in more natural looking C
code. For instance, in the download you will find a second version of
set_text() as described above, but without the portability macros. So, I would
like to know if you think we should (A) Keep the macros - portability is
important to serious developers, (B) Get rid of them - who cares about Intel
chips anyway, or (C) Who cares? I'll tally the votes in two weeks and announce
the results here.
.SH STAY TUNED!
As well as answers to feedback questions, the next column will
discuss how GEM objects are linked to form trees, and how to use AES calls and
your own code to manipulate them for fun and profit. In the following
installment, we'll look at the VDI raster operations (also known as "blit"
functions).
.!
.!
.!*****************************************************************************
.!* *
.!* End Part 4 *
.!* *
.!*****************************************************************************